package cn.com.joycode.nimble.admin.security.configuration;

import cn.com.joycode.nimble.admin.security.authentication.NimbleAdminAuthenticationEntryPoint;
import cn.com.joycode.nimble.admin.security.authentication.NimbleAdminAuthenticationProvider;
import cn.com.joycode.nimble.admin.security.authentication.NimbleAdminVoter;
import org.springframework.context.annotation.Bean;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.vote.AuthenticatedVoter;
import org.springframework.security.access.vote.UnanimousBased;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.access.expression.WebExpressionVoter;
import org.springframework.web.cors.CorsUtils;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

@EnableWebSecurity
public class NimbleAdminWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    /**
     * 触发登录页面的入口
     */
    public static final String LOGIN_URL = "/public/view/auth/login";

    public static final String LOGIN_PAGE_URL = "/public/view/auth/login";

    /**
     * form登录表单提交处理的入口
     */
    public static final String LOGIN_PROCESSING_URL = "/api/auth/login";

    /**
     * 处理登出的入口
     */
    public static final String LOGOUT_URL = "/public/api/auth/logout";

    /**
     * 处理api登录的入口,不能以/public开头
     */
    public static final String LOGIN_API_URL = "/api/auth/login";

    @Resource
    private NimbleAdminAuthenticationProvider nimbleAdminAuthenticationProvider;

    @Resource
    private NimbleAdminSecurityConfigurerAdapter nimbleAdminSecurityConfigurerAdapter;

    @Resource
    public NimbleAdminAuthenticationEntryPoint nimbleAdminAuthenticationEntryPoint;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //http.addFilterBefore(new NimbleAdminOncePerRequestFilter(), UsernamePasswordAuthenticationFilter.class);
//        http.authorizeRequests().antMatchers("**").permitAll();
//        http.formLogin().loginPage("/webjars/pear-admin/view/auth/login").loginProcessingUrl("/webjars/pear-admin/api/auth/login").permitAll();
//        http.logout().clearAuthentication(true).invalidateHttpSession(true).permitAll();
//        http.authorizeRequests().anyRequest().authenticated();
//        http.csrf().disable();

        http.formLogin().loginPage(LOGIN_URL).permitAll().and().logout()//

                //.loginProcessingUrl(LOGIN_PROCESSING_URL)
                //.successHandler(apiAuthenticationSuccessHandler)
                //.failureHandler(apiAuthenticationFailureHandler)
                //.permitAll()
                //.and().rememberMe()
                //.tokenRepository(persistentTokenRepository)
                //.userDetailsService(apiUserDetailsService)
                //.tokenValiditySeconds(3600)
                //.and().logout()
                .logoutUrl(LOGOUT_URL)
                //.logoutSuccessHandler(apiLogoutSuccessHandler)
                .invalidateHttpSession(true)
                .clearAuthentication(true)
                .permitAll()
                .and().exceptionHandling()
                //.accessDeniedHandler(apiAccessDeniedHandler)
                .authenticationEntryPoint(nimbleAdminAuthenticationEntryPoint)
                .and().authorizeRequests()
                .requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
                .antMatchers("/public/**").permitAll()
                .anyRequest()
                .authenticated()
                .accessDecisionManager(accessDecisionManager());
        //
        http.apply(nimbleAdminSecurityConfigurerAdapter);
        http.csrf().disable();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        // 配置需要忽略的静态资源或页面控制器入口，不能配置授权过滤器的url
        web.ignoring().antMatchers("/*.ico", "/public/**", "/error/**", "/webjars/**");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // auth.authenticationProvider(nimbleAdminAuthenticationProvider);
    }

    @Bean
    public AccessDecisionManager accessDecisionManager() {
        List<AccessDecisionVoter<? extends Object>> decisionVoters
                = Arrays.asList(
                new WebExpressionVoter(),
                // new RoleVoter(),
                new NimbleAdminVoter(),
                new AuthenticatedVoter());
        return new UnanimousBased(decisionVoters);
    }
}